package com.example.week02.day4.CustomView;

import android.content.Context;
import android.graphics.*;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;

import java.util.*;

//弹幕自定义view
public class DanmuView extends View {
    private static final String TAG = "DanmuView---";

    //弹幕列表
    private final List<DanmuItem> danmuList = new ArrayList<>();
    private final Paint paint = new Paint();
    private final Random random = new Random();
    private int viewWidth, viewHeight;
    private boolean isRunning = true;
    private final Handler handler = new Handler(); // 弹幕暂停/恢复计时器
    private boolean isLongPress = false; // 长按加速状态
    private boolean isDoubleTapSlow = false; // 双击减速状态
    private GestureDetector gestureDetector; // 手势检测器
    private final Handler speedHandler = new Handler(); // 全局速度状态控制器

    //弹幕字体大小
    private final int danmuFontSize = 65;
    //弹幕轨道间距
    private final int danmuPadding = 65;

    // 最近使用轨道队列
    private final Queue<Integer> recentTracks = new LinkedList<>();
    // 轨道重用间隔控制
    private static final int QUEUE_SIZE = 4;
    // 添加轨道状态跟踪器
    private final Map<Integer, Float> trackLastEndX = new HashMap<>();
    private int maxTracks = 0;
    List<DanmuItem> toRemove = new ArrayList<>();



    //弹幕类
    public static class DanmuItem {
        String text;
        float x;
        float y;
        float relX;
        float relY;
        float speed;
        int color;
        float textSize;
        boolean isPaused; //暂停状态
        //判断弹幕是否从屏幕走完
        boolean isFinish;
        //弹幕字数
        int textNum;
        long pauseStartTime; //暂停开始时间
        //定时恢复：弹幕暂停3秒后自动恢复
        //状态切换：双击减速后自动恢复速度
        //线程切换：确保UI刷新在主线程执行
        Runnable resumeTask;
        float baseSpeed; //基础速度替换原来的speed
        //记录弹幕所在的轨道索引
        int trackIndex;
    }

    // 初始化手势检测器
    private void initGestureDetector() {
        gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
            //按下屏幕
            @Override
            public boolean onDown(@NonNull MotionEvent e) {
                return true; // 必须返回true才能接收后续事件
            }

            //长按
            @Override
            public void onLongPress(@NonNull MotionEvent e) {
                if (!isRunning) return;
                isLongPress = true;
                postInvalidate();
                Log.d("DanmuView", "长按加速激活");
            }

            //双击
            @Override
            public boolean onDoubleTap(@NonNull MotionEvent e) {
                // 取消之前的恢复任务
                if (!isRunning) return false;
                speedHandler.removeCallbacksAndMessages(null);
                isDoubleTapSlow = true;
                //postInvalidate请求 View 在 UI 线程中重新绘制自身
                postInvalidate();
                Log.d("DanmuView", "双击减速激活");

                // 3秒后自动恢复速度
                speedHandler.postDelayed(() -> {
                    isDoubleTapSlow = false;
                    postInvalidate();
                    Log.d("DanmuView", "双击减速状态结束");
                }, 3000);

                return true;
            }

            //单击屏幕 暂停所有弹幕
            @Override
            public boolean onSingleTapConfirmed(@NonNull MotionEvent e) {
                // 处理单击事件
                float x = e.getX();
                float y = e.getY();
                //判断单击是否为弹幕
                DanmuItem clickedDanmu = findClickedDanmu(x, y);
                if (clickedDanmu != null) {
                    //是单个弹幕调用方法暂停当前单个弹幕
                    toggleDanmuPauseState(clickedDanmu);
                } else {
                    //点击为屏幕，调用方法暂停所有弹幕
                    toggleRunning();
                }
                return true;
            }
        });
    }

    // 暂停/恢复所有弹幕的方法
    public void toggleRunning() {
        isRunning = !isRunning;  // 切换全局运行标志
        if (isRunning) {
            isLongPress = false;  // 重置长按加速
            isDoubleTapSlow = false;  // 重置双击减速
            speedHandler.removeCallbacksAndMessages(null); // 清理速度恢复任务
        }
        postInvalidate();  // 请求重绘
    }


    //触摸事件检测
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 将事件传递给手势检测器
        gestureDetector.onTouchEvent(event);

        // 处理长按结束
        if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
            if (isLongPress) {
                isLongPress = false;
                postInvalidate();
                Log.d("DanmuView", "长按加速结束");
            }
        }

        return true; // 始终消费触摸事件
    }

    //查找被点击的弹幕
    private DanmuItem findClickedDanmu(float x, float y) {
        synchronized (danmuList) {
            // 从后往前遍历（上层弹幕优先）
            for (int i = danmuList.size() - 1; i >= 0; i--) {
                DanmuItem item = danmuList.get(i);

                // 计算弹幕文本的矩形区域
                float textWidth = paint.measureText(item.text);
                Rect textBounds = new Rect();
                paint.getTextBounds(item.text, 0, item.text.length(), textBounds);
                float textHeight = textBounds.height();

                // 计算弹幕的矩形区域
                float left = item.x;
                float top = item.y - textHeight;
                float right = item.x + textWidth;
                float bottom = item.y + textHeight * 0.5f; // 基线以下区域

                // 检查点击是否在弹幕区域内
                if (x >= left && x <= right && y >= top && y <= bottom) {
                    return item;
                }
            }
            return null;
        }
    }

    //切换单个弹幕的暂停状态
    private void toggleDanmuPauseState(DanmuItem danmu) {
        if (danmu.isPaused) {
            // 如果已经暂停，提前恢复
            resumeDanmu(danmu);
            Log.d("DanmuView", "弹幕提前恢复: " + danmu.text);
        } else {
            // 暂停弹幕
            pauseDanmu(danmu); // 默认暂停3秒
            Log.d("DanmuView", "弹幕暂停: " + danmu.text);
        }
        postInvalidate();
    }

    //暂停单个弹幕
    private void pauseDanmu(DanmuItem danmu) {
        if (danmu.resumeTask != null) {
            handler.removeCallbacks(danmu.resumeTask);
        }

        danmu.isPaused = true;
        danmu.pauseStartTime = System.currentTimeMillis();

        // 创建恢复任务
        danmu.resumeTask = () -> {
            if (danmu.isPaused) {
                danmu.isPaused = false;
                postInvalidate();
                Log.d("DanmuView", "弹幕自动恢复: " + danmu.text);
            }
        };

        // 延迟执行恢复任务
        handler.postDelayed(danmu.resumeTask, 3000);
    }

    //恢复单个弹幕
    private void resumeDanmu(DanmuItem danmu) {
        if (danmu.resumeTask != null) {
            handler.removeCallbacks(danmu.resumeTask);
            danmu.resumeTask = null;
        }
        danmu.isPaused = false;
    }

    // 保存弹幕状态
    public List<DanmuItem> saveDanmuState() {
        synchronized (danmuList) {
            for (DanmuItem item : danmuList) {
                if (viewWidth > 0 && viewHeight > 0) {
                    item.relX = item.x / viewWidth;
                    item.relY = item.y / viewHeight;
                }
            }
            return new ArrayList<>(danmuList);
        }
    }

    // 恢复弹幕状态
    public void restoreDanmuState(List<DanmuItem> savedList) {
        if (savedList == null || savedList.isEmpty()) return;

        synchronized (danmuList) {
            danmuList.clear();
            for (DanmuItem item : savedList) {
                item.x = item.relX * viewWidth;
                item.y = item.relY * viewHeight;
                // 恢复时重置暂停状态
                item.isPaused = false;
                if (item.resumeTask != null) {
                    handler.removeCallbacks(item.resumeTask);
                    item.resumeTask = null;
                }
                danmuList.add(item);
            }
        }
        postInvalidate();
    }

    //获取屏幕宽高
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // 屏幕尺寸变化时重置轨道状态
        trackLastEndX.clear();
        recentTracks.clear();

        List<DanmuItem> savedState = saveDanmuState();
        viewWidth = w;
        viewHeight = h;
        if (!savedState.isEmpty()) {
            restoreDanmuState(savedState);
        }
        Log.d("DanmuView", "尺寸更新: " + w + "x" + h);
    }

    public DanmuView(Context context) {
        super(context);
        init();
    }

    public DanmuView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    //初始化画布和手势检测器
    private void init() {
        paint.setAntiAlias(true);
        paint.setTextSize(36);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.FILL);
        initGestureDetector();
    }

    //弹幕初始化
    public void addDanmu(String text) {
        DanmuItem item = new DanmuItem();
        item.text = text;
        item.textNum = text.length();
        item.isFinish = false;

        Log.d(TAG, "---添加弹幕前 | 列表大小: " + danmuList.size() + " | 内容: " + getDanmuListContent());

        item.x = viewWidth > 0 ? viewWidth : getWidth();
        //设置起始y轴坐标
        item.y = getRandomY();

        if (viewWidth > 0) {
            item.relX = 1.0f;
            item.relY = item.y / viewHeight;
        }

        item.speed = 4.0f;
        item.baseSpeed = 4.0f;
        item.color = Color.BLACK;
        item.textSize = danmuFontSize;
        item.isPaused = false; // 初始状态为未暂停

        synchronized (danmuList) {
                danmuList.add(item);
        }

        // 添加弹幕后打印列表详情
        Log.d(TAG, "---添加弹幕后 | 列表大小: " + danmuList.size() +
                " | 新弹幕: \"" + item.text + "\" | 内容: " + getDanmuListContent());
        postInvalidate();
    }

    //发送位置设置
    private float getRandomY() {
        //获取View的实际高度 优先使用已存储的viewHeight，若未初始化则实时获取
        int height = viewHeight > 0 ? viewHeight : getHeight();
        //处理极端小高度情况
        if (height <= 70) return 70;

        //弹幕轨道高度
        float trackHeight = danmuPadding+danmuFontSize;
        //最多轨道个数  竖屏16 横屏6
        int maxTracks = Math.max(1, (int) ((height - 50) / trackHeight));


        // 初始化轨道状态 -1 表示轨道可用
        if (trackLastEndX.isEmpty()) {
            for (int i = 0; i < maxTracks; i++) {
                trackLastEndX.put(i, -1f);
            }
        }

        // 创建可用轨道列表（轨道上无弹幕或弹幕已完全移出屏幕）
        List<Integer> availableTracks = new ArrayList<>();
        for (int i = 0; i < maxTracks; i++) {
            Float lastEndX = trackLastEndX.get(i);
            if (lastEndX == null || lastEndX < 0) {
                availableTracks.add(i);
            }
        }
        //将要使用的轨道
        int selectedTrack;

        // 优先使用空闲轨道
        if (!availableTracks.isEmpty()) {
            selectedTrack = availableTracks.get(random.nextInt(availableTracks.size()));
        }
        // 当所有轨道都有弹幕时，选择最近未使用的轨道
        else {
            List<Integer> candidateTracks = new ArrayList<>();
            for (int i = 0; i < maxTracks; i++) {
                if (!recentTracks.contains(i)) {
                    candidateTracks.add(i);
                }
            }

            selectedTrack = candidateTracks.isEmpty() ?
                    random.nextInt(maxTracks) :
                    candidateTracks.get(random.nextInt(candidateTracks.size()));
        }

        // 更新最近使用轨道队列
        if (recentTracks.size() >= QUEUE_SIZE) {
            recentTracks.poll();
        }
        recentTracks.offer(selectedTrack);

        // 标记轨道已被占用
        // 初始设置为屏幕外右侧
        trackLastEndX.put(selectedTrack, viewWidth * 2f);

        // 计算Y坐标
        float baseY = 70 + selectedTrack * trackHeight;
        return baseY ;
    }

    //用于在画布(Canvas)上绘制视图的可视内容
    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        // 绘制背景和边框
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        paint.setColor(Color.GRAY);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        canvas.drawRect(0, 0, viewWidth, viewHeight, paint);
        paint.setStyle(Paint.Style.FILL);

        // 新建数组存储需要移除的弹幕移出屏幕的danmuList元素地址


        synchronized (danmuList) {
            // 重置轨道状态
            for (int i = 0; i < maxTracks; i++) {
                trackLastEndX.put(i, -1f);
            }
            //更新所有弹幕位置并检查是否移出屏幕
            for (DanmuItem item : danmuList) {
                // 更新弹幕位置（如果运行中且未暂停）
                if (isRunning && !item.isPaused) {
                    float actualSpeed = item.baseSpeed;
                    if (isLongPress) {
                        actualSpeed *= 2.0f; // 长按加速
                    } else if (isDoubleTapSlow) {
                        actualSpeed *= 0.5f; // 双击减速
                    }
                    //向左移动
                    item.x -= actualSpeed;
                }

                // 计算弹幕结束位置
                //计算文本在屏幕上的逻辑宽度
                float itemWidth = paint.measureText(item.text);
                //当前弹幕的尾部位置
                float itemEndX = item.x + itemWidth;

                // 获取当前轨道的最新结束位置
                Float currentEndX = trackLastEndX.get(item.trackIndex);
                //如果当前轨道有最新弹幕
                if (currentEndX == null || itemEndX > currentEndX) {
                    //更新轨道的最远点
                    trackLastEndX.put(item.trackIndex, itemEndX);
                }

                // 检查弹幕是否完全移出屏幕
                //宽度和x坐标相加小于0说明在屏幕外
                if (item.x + itemWidth < 0) {
                    item.isFinish = true;
                    if (item.resumeTask != null) {
                        handler.removeCallbacks(item.resumeTask);
                    }
                    toRemove.add(item);
                }
            }

            //移除移出屏幕的弹幕
            if (!toRemove.isEmpty()) {
                // 记录移除日志
                int removedCount = toRemove.size();
                int prevSize = danmuList.size();

                //移除danmuList中toRemove标记的元素
                danmuList.removeAll(toRemove);

                // 记录移除详情
                Log.d(TAG, "===== 弹幕移除详情 =====");
                Log.d(TAG, "移除数量: " + removedCount + "/" + prevSize);
                for (int i = 0; i < toRemove.size(); i++) {
                    DanmuItem item = toRemove.get(i);
                    Log.d(TAG, "---" + (i + 1) + " 移除弹幕: \"" + item.text.substring(0, Math.min(10, item.text.length()))
                            + (item.text.length() > 10 ? "..." : "") + "\"");
                }
            }

            //绘制所有弹幕
            for (DanmuItem item : danmuList) {
                paint.setColor(item.color);
                paint.setTextSize(item.textSize);
                paint.setAlpha(item.isPaused ? 150 : 255);
                canvas.drawText(item.text, item.x, item.y, paint);
            }

            //记录弹幕数量
            if (danmuList.size() > 50) {
                Log.d(TAG, "---弹幕数量较多: " + danmuList.size() + "条");
            }

        }

        // 重置画笔状态
        paint.setAlpha(255);
        paint.setColor(Color.BLACK);

        // 持续刷新视图
        if (isRunning) {
            postInvalidateDelayed(10); // 10ms后重绘
        }

    }


    // 添加视图销毁时的清理
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        speedHandler.removeCallbacksAndMessages(null);
    }


    // 获取弹幕列表内容方法
    private String getDanmuListContent() {
        if (danmuList.isEmpty()) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder("[");
        for (DanmuItem item : danmuList) {
            sb.append("\"").append(item.text).append("\", ");
        }
        // 移除最后一个逗号和空格
        sb.setLength(sb.length() - 2);
        sb.append("]");

        return sb.toString();
    }


}